<template>
  <div class="wrap">
    <div
      class="origin"
      :style="{
        width: `${initWidth}px`,
        height: `${initHeight}px`,
      }"
    >
      <div
        class="event-view"
        @mouseenter="mouseenter"
        @mousemove="mousemove"
        @mouseleave="mouseleave"
      ></div>
      <img class="img" :src="url" />
      <div
        class="mask"
        v-show="data.show"
        :style="{
          width: `${initWidth / zoom}px`,
          height: `${initHeight / zoom}px`,
          left: `${data.maskLeft}px`,
          top: `${data.maskTop}px`,
        }"
      ></div>
    </div>

    <div
      class="per-view"
      v-show="data.show"
      :style="{
        width: `${initWidth}px`,
        height: `${initHeight}px`,
      }"
    >
      <img
        class="img"
        :style="{
          width: `${initWidth * zoom}px`,
          height: `${initHeight * zoom}px`,
          left: `${data.perviewLeft}px`,
          top: `${data.perviewTop}px`,
        }"
        :src="url"
      />
    </div>
  </div>
</template>

<script setup>
import { reactive, defineProps } from "vue";
const props = defineProps({
  zoom: {
    type: Number,
    default: 2,
  },
  url: {
    type: String,
    required: true,
    default: "https://temp.im/200x200/4CD964/fff",
  },
  initWidth: {
    type: Number,
    default: 400,
  },
  initHeight: {
    type: Number,
    default: 400,
  },
});
const data = reactive({
  show: false,
  maskLeft: 0,
  maskTop: 0,
  perviewLeft: 0,
  perviewTop: 0,
});

const mouseenter = () => {
  data.show = true;
};

const mousemove = (e) => {
  const { offsetX, offsetY } = e;
  const { initWidth, initHeight, zoom } = props;
  const maskWidth = initWidth / zoom;
  const maskHeight = initHeight / zoom;
  let viewX, viewY;
  viewX = offsetX - maskWidth / 2;
  viewY = offsetY - maskHeight / 2;

  // 边界判断
  viewX = viewX < 0 ? 0 : viewX;
  viewY = viewY < 0 ? 0 : viewY;
  if (viewX + maskWidth >= initWidth) {
    viewX = initWidth - maskWidth;
  }
  if (viewY + maskHeight >= initHeight) {
    viewY = initHeight - maskHeight;
  }

  data.maskLeft = viewX;
  data.maskTop = viewY;
  data.perviewLeft = -viewX * props.zoom;
  data.perviewTop = -viewY * props.zoom;
};

const mouseleave = () => {
  data.show = false;
};
</script>
<style lang="scss" scoped>
.wrap {
  display: flex;
}
.origin {
  position: relative;
  .event-view {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 999;
  }
  .img {
    width: 100%;
    height: 100%;
  }
  .mask {
    position: absolute;
    background: rgba(255, 255, 255, 0.4);
  }
}
.per-view {
  position: relative;
  margin-left: 20px;
  overflow: hidden;
  .img {
    position: absolute;
    z-index: 1000;
  }
}
</style>
